#ifndef TCPMGR_H
#define TCPMGR_H
#include <QTcpSocket>
#include "../_singleton.h"
#include "../Def.h"
#include <functional>
#include <QObject>
#include <QJsonArray>
#include <qthread.h>
#include <memory>
#include <queue>
#include "../sql/sqlite/historydao.h"

class TcpThread:public std::enable_shared_from_this<TcpThread> {
public:
    TcpThread();
    ~TcpThread();
    QThread* thread() {return _tcp_thread;}
private:
    QThread* _tcp_thread;
};

class TcpMgr:public QObject, public _Singleton<TcpMgr>,
               public std::enable_shared_from_this<TcpMgr>
{
    Q_OBJECT
public:
    ~TcpMgr();
private:
    friend class _Singleton<TcpMgr>;
    TcpMgr();
    void initHandlers();
    void handleMsg(ReqId id, int len, QByteArray data);
    void registerMetaType();
    QTcpSocket* _socket; // 改为指针
    QString _host;
    uint16_t _port;
    QByteArray _buffer;
    bool _b_recv_pending;
    quint16 _message_id;
    quint16 _message_len;
    QMap<ReqId, std::function<void(ReqId id, int len, QByteArray data)>> _handlers;

    QMap<QString, FileInfo> _uploadContext; // key: file_hash, value: 待同步的FileInfo
    QMap<int32_t, FileInfo> _downloadContext; // key: file_id, value: 备份记录信息

    //发送队列
    std::queue<QByteArray> _send_queue;
    //正在发送的包
    QByteArray _current_block;
    //当前已发送的字节数
    qint64 _bytes_sent;
    //是否正在发送
    bool _pending = false;
public slots:
    void slot_tcp_connect(ServerInfo);
    void slot_send_data(ReqId reqId, QByteArray data);
    void slot_sendUploadRequest(const QByteArray& data, const FileInfo& info);
    void slot_sendDownloadRequest(const QByteArray& data, const FileInfo& info);

    void initSocket(); // 初始化QTcpSocket
signals:
    void sig_con_success(bool bsuccess);
    void sig_send_data(ReqId reqId, QByteArray data);

    void sig_swich_mainwindow();
    void sig_login_failed(int);
    void sig_uploadFinished(FileInfo);
    void sig_addBackupRecord(FileInfo);
    void sig_downloadFinished(int);

    void sig_sendUploadRequest(const QByteArray& data, const FileInfo& info);
    void sig_sendDownloadRequest(const QByteArray& data, const FileInfo& info);
};

#endif // TCPMGR_H
